package DataBase;

import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import org.apache.derby.drda.NetworkServerControl;

public class DBAccess extends Thread{

    public void DBAccess() {
    }
    private String protocol = "jdbc:derby://localhost:1527/";
    private String dbName = "socofWebGet";
    private String driver = "org.apache.derby.jdbc.ClientDriver";

    // Para arrancar automaticamente
    public void init() {

        //Registar o driver
        try {
            DriverManager.registerDriver(new org.apache.derby.jdbc.ClientDriver());

            PrintWriter saida = new PrintWriter(System.out, true);
            NetworkServerControl server = new NetworkServerControl();
            server.start(saida);
            //    } catch (SQLException se){
        } catch (Exception e) {
            System.err.println(e.toString());
        }

        try {
            Class.forName(driver).newInstance();
        } catch (java.lang.ClassNotFoundException e) {
            System.err.print("ClassNotFoundException: ");
            System.err.println(e.getMessage());
        } catch (Exception e) {
            System.out.println("Erro ao arrancar o ClientDriver");
            return;
        }
    }

    public Connection connection() {
        Connection conn = null;

        try {
            conn = DriverManager.getConnection(protocol + dbName+ ";create=true", "SOCOF", "socof");

        } catch (SQLException se) {

            if (se.getErrorCode() == 40000 && ("XJ040".equals(se.getSQLState()))) {
                System.out.println("Base de dados ja arrancada 1.");
                conn = connection();
                return conn;
            } else if (se.getErrorCode() == 45000 && ("XSDB6".equals(se.getSQLState()))) {
                System.out.println("Base de dados ja arrancada 2.");
                conn = connection();
                return conn;
            } else if (se.getErrorCode() == 40000 && ("08004".equals(se.getSQLState()))) {
                System.out.println("Base de dados ja arrancada. Vou tentar ligar de outra forma.");
                try {
                 conn = DriverManager.getConnection(protocol + dbName , "", "");
                } catch (SQLException se2){
                    // Excepcao inesperada
                    System.err.println("Erro desconhecido ao ligar a BD.");
                    printSQLException(se2);
                }
                return conn;
            }
            else {
                // Excepcao inesperada (shutdown failed)
                System.err.println("A DB Derby nao encerrou normalmente.");
                printSQLException(se);
            }
        }
        return conn;

    }

    // PARA DESLIGAR BD - É boa pratica e torna o arranque mais rapido
    // uma vez que assim o derby não tem que fazer verificações no arranque
    public void shutdown() {
        try {
            //Desliga So a nossa BD:
            //DriverManager.getConnection(protocol + dbName +";shutdown=true", "SOCOF", "socof");
            //Desliga TODAS AS BD
            //DriverManager.getConnection(protocol + ";shutdown=true");
            DriverManager.getConnection(protocol + dbName + ";shutdown=true", "SOCOF", "socof");
        } catch (SQLException se) {
            if (((se.getErrorCode() == -1)
                    && ("08006".equals(se.getSQLState())))) {
                // Excepcao prevista
                System.out.println("A DB Derby encerrou normalmente.");
            } else {
                // Excepcao inesperada (shutdown failed)
                System.err.println("A DB Derby nao encerrou normalmente.");
                printSQLException(se);
            }
        }
    }

    //</editor-fold>
    //Para poder limpar e criar BD rapidamente
    public void criaTabelaOmissao() {
        String tabelaFxCriar = "FICHEIROS";
        String colunasFxCriar = "\"ID\" INTEGER not null "
                + "PRIMARY KEY GENERATED ALWAYS AS IDENTITY "
                + "(START WITH 1, INCREMENT BY 1), "
                + "\"DOMINIO\" VARCHAR(100), "
                + "\"FICHEIRO\" VARCHAR(100), "
                + "\"ESTADO\" VARCHAR(30), "
                + "\"TAMANHOSITE\" INTEGER, "
                + "\"CAMINHOLOCAL\" VARCHAR(250) ,"
                + "\"CAMINHOSITE\" VARCHAR(250) not null, UNIQUE(\"CAMINHOSITE\"),"
                + "\"TIPO\" VARCHAR(30), "
                + "\"NIVEIS\" INTEGER, "
                + "\"ACTUALIZADO\" date";

        DBAccess ligacao = new DBAccess();
        ligacao.init();

        ligacao.connection();
        ligacao.createTable(tabelaFxCriar, colunasFxCriar);
        ligacao.shutdown();
    }

// Para apagar tabelas.
    public boolean deleteTable(String table) {
        boolean resultado = false;
        try {
            Connection ligacao = connection();
            Statement deletion = ligacao.createStatement();
            resultado = deletion.execute("DROP TABLE " + table.toUpperCase());
            deletion.close();
            ligacao.close();
        } catch (SQLException se) {
            if ((se.getErrorCode() == 30000) && ("42Y55".equals(se.getSQLState()))) {
                System.out.println("Erro ao apagar: Tabela " + table.toUpperCase() + " nao existente");
            } else {
                System.err.println("Erro inesperado ao apagar a tabela. deleteTable(String table)");
                printSQLException(se);
            }
        }
        return resultado;
    }

// Para mostrar todas as tabelas da DB
    public void sqlShowAllTables() {

        try {
            Connection ligacao = connection();
            Statement creation = ligacao.createStatement();

            DatabaseMetaData dbmd = ligacao.getMetaData();
            ResultSet resultSet = dbmd.getTables(null, null, null, null);
            while (resultSet.next()) {
                String strTableName = resultSet.getString("TABLE_NAME");
                System.err.println("TABLE_NAME is " + strTableName);

            }
            creation.close();
            ligacao.close();
        } catch (SQLException se) {
            se.printStackTrace();
        } catch (Exception e) {
            System.out.println(e.toString());
        }
    }

// Para fazer um select recebido por argumento.
    public void sqlSelect(String sqlCommand) {

        try {
            Connection ligacao = connection();
            Statement select = ligacao.createStatement();
            ResultSet result = select.executeQuery(sqlCommand);

            System.out.println("SQLSelect   :");
            while (result.next()) { // process results one row at a time
                String FICHEIRO = result.getString("FICHEIRO");
                String ESTADO = result.getString("ESTADO");

                System.out.println("FICHEIRO = " + FICHEIRO);
                System.out.println("ESTADO = " + ESTADO);
            }
            select.close();
            ligacao.close();
        } catch (SQLException se) {
            if ((se.getErrorCode() == 30000) && ("42X05".equals(se.getSQLState()))) {
                System.out.println("Erro ao fazer SELECT: Tabela nao existente. sqlSelect(String sqlCommand)");
            } else {
                System.err.println("Erro inesperado ao fazer SELECT. sqlSelect(String sqlCommand)");
                printSQLException(se);
            }
        }
    }

// Para criar tabela com estrutura.
// Recebe no 1o argumento nome da tabela
// Recebe no 2o argumento string de criacao das colunas
    public boolean createTable(String table, String columns) {
        boolean resultado = false;
        String tabela = table.toUpperCase();
        String create = "CREATE TABLE \"" + tabela + "\" (" + columns + ")";
//        System.out.println("Vou criar o seguinte: " + create);
        try {
            Connection ligacao = connection();
            Statement creation = ligacao.createStatement();
            resultado = creation.execute(create);

            creation.close();
            ligacao.close();
        } catch (SQLException se) {
            se.printStackTrace();
        } catch (Exception e) {
            System.out.println(e.toString());
        }
        return resultado;
    }

// Ja insere e trata erros conforme
    private int sqlFxInsert(Ficheiro dados) throws SQLException {
        boolean resultadoExecucao = false;
        int idResultante = -1;
        Connection ligacao = connection();
        String sqlInsertCommand = "Insert into \"FICHEIROS\" ("
                + "\"DOMINIO\", "
                + "\"FICHEIRO\", "
                + "\"ESTADO\", "
                + "\"TAMANHOSITE\", "
                + "\"CAMINHOSITE\", "
                + "\"CAMINHOLOCAL\", "
                + "\"TIPO\", "
                + "\"NIVEIS\", "
                + "\"ACTUALIZADO\") values ('"
                + dados.getDominio().toLowerCase() + "', '" + dados.getFicheiro() + "', '"
                + dados.getEstado().toUpperCase() + "', " + dados.getTamanhosite() + ", '"
                + dados.getCaminhosite() + "', '" + dados.getCaminholocal() + "', '"
                + dados.getTipo().toUpperCase() + "', " + dados.getNiveis() + ", CURRENT DATE)";

        Statement insert = ligacao.createStatement();

        try {
            insert.executeUpdate(sqlInsertCommand, Statement.RETURN_GENERATED_KEYS);

            ResultSet resInsert = insert.getGeneratedKeys();
            resInsert.next();
            System.err.println("Apos insercao ficou com ID: " + resInsert.getInt(1));
            idResultante = resInsert.getInt(1);
            resultadoExecucao = true;
        } catch (SQLException se) {
            if (((se.getErrorCode() == 30000)
                    && ("23505".equals(se.getSQLState())))) {
                System.err.println("Registo duplicado. Nao foi possivel inserir. sqlFxInsert(Ficheiro dados)");
            } else if (((se.getErrorCode() == -1)
                    && ("23505".equals(se.getSQLState()))))
            { 
                //System.err.println("Registo propositadamente ignorado");
                resultadoExecucao = true;
            } else {
                System.err.println("Outro erro ao inserir registo. sqlFxInsert(Ficheiro dados)");
                printSQLException(se);
            }
        }
        if (!resultadoExecucao) {
            System.err.println("Erro ao Inserir................ sqlFxInsert(Ficheiro dados)");
            return idResultante;
        }
        System.out.println("Inserido com sucesso!!!!!!!!!!!!!!");
        return idResultante;
    }

//Se nao existir adiciona, se existir, actualiza
//EM QQE um dos casos, devolvera o id
// se id = -1 ERRO...
    public int writeData(Ficheiro dados) {
        System.out.println("Recebi fx com id: " + dados.getId());
        int resultado = -1;
        int fxId = -1;
        // se  existir
        //  Actualiza

        if ((dados.getId() == null) || (!sqlExisteId(dados))) {
// Se id  null -> ve se existe pelo caminho
            fxId = sqlExisteFxCaminhoSite(dados);
// Se nao existir, adiciona e devolve id
            if (-1 == fxId) {
                System.out.println("Vou Inserir");
                try {
                    resultado = sqlFxInsert(dados);
                } catch (SQLException ex) {
                    printSQLException(ex);
                }
            }
        }// Se existir, BUSCA O ID E actualiza O BICHO
        else {
            try {
                if (dados.getId() != null) {
                    //trouxe o meu proprio ID, portanto actualizo-o
                    System.out.println("Vou actualizar");
                    resultado = sqlFxUpdate(dados);
                } else { // tem de ser o ID obtido pelo caminho
                    dados.setId(fxId);
                    System.out.println("Vou actualizar");
                    resultado = sqlFxUpdate(dados);
                }
            } catch (SQLException ex) {
                printSQLException(ex);
            }
        }
        return resultado;
    }

//Se nao existir adiciona, se existir, actualiza
//EM QQE um dos casos, devolvera o id
    public void writeData(ArrayList<Ficheiro> listaCompleta) {

        for (Ficheiro ficheiro : listaCompleta) {
            writeData(ficheiro);
        }
    }

// Para actualizar existentes
    private int sqlFxUpdate(Ficheiro dados) throws SQLException {
        boolean resultadoExecucao = false;
        int idExecutado = -1;
        Connection ligacao = connection();
        String sqlUpdateCommand = "UPDATE \"FICHEIROS\" set "
                + "\"DOMINIO\"= '" + dados.getDominio().toLowerCase()
                + "',\"FICHEIRO\"= '" + dados.getFicheiro()
                + "',\"ESTADO\"= '" + dados.getEstado().toUpperCase()
                + "',\"TAMANHOSITE\"= " + dados.getTamanhosite()
                + ",\"CAMINHOSITE\"= '" + dados.getCaminhosite()
                + "',\"CAMINHOLOCAL\"= '" + dados.getCaminholocal()
                + "',\"TIPO\"= '" + dados.getTipo().toUpperCase()
                + "',\"NIVEIS\"= " + dados.getNiveis()
                + ",\"ACTUALIZADO\"= CURRENT DATE "
                + "where \"ID\"=" + dados.getId();
        System.out.println(sqlUpdateCommand);
        Statement update = ligacao.createStatement();

        try {
            update.executeUpdate(sqlUpdateCommand, Statement.RETURN_GENERATED_KEYS);

            resultadoExecucao = true;
            idExecutado = dados.getId();
        } catch (SQLException se) {
            if (((se.getErrorCode() == 30000)
                    && ("23505".equals(se.getSQLState())))) {
                System.err.println("Registo duplicado. Nao actualizei. private int sqlFxUpdate(Ficheiro dados) throws SQLException");
            } else {
                System.err.println("Outro erro ao actualizar registo. private int sqlFxUpdate(Ficheiro dados) throws SQLException");
                printSQLException(se);
            }
        }
        if (!resultadoExecucao) {
            System.err.println("Erro ao actualizar valores. private int sqlFxUpdate(Ficheiro dados) throws SQLException");
            return idExecutado;
        }
        System.out.println("Actualizado com sucesso! private int sqlFxUpdate(Ficheiro dados) throws SQLException");
        return idExecutado;
    }

// Para saber se já existe o ficheiro passando objecto
    public boolean sqlExisteId(Ficheiro dados) {
        boolean existencia = false;
        System.err.println("Vou testar se existe o ID " + dados.getId() + "public boolean sqlExisteId(Ficheiro dados)");
        if (dados.getId() == null) {
            System.err.println("Recebi um in null em :" + dados.getFicheiro() + "public boolean sqlExisteId(Ficheiro dados)");
            return existencia;
        }
        try {
            Connection ligacao = connection();
            Statement select = ligacao.createStatement();
            ResultSet result = select.executeQuery("SELECT ID FROM \"FICHEIROS\" WHERE \"ID\"="
                    + dados.getId());

            while (result.next()) { // processa resultados, um a um
                if (result.getInt(1) > 0) {
                    existencia = true;
                }
            }
            select.close();
            ligacao.close();
        } catch (SQLException se) {
            if ((se.getErrorCode() == 30000) && ("42X05".equals(se.getSQLState()))) {
                System.out.println("Erro ao fazer SELECT: Tabela nao existente. public boolean sqlExisteId(Ficheiro dados)");
            } else {
                System.err.println("Erro inesperado ao fazer SELECT. public boolean sqlExisteId(Ficheiro dados)");
                printSQLException(se);
            }
        }
        return existencia;
    }
//sqlExisteFxCaminhoSite(dados)
    // Para saber se já existe o ficheiro passando objecto
    // -1 se nao existir
    // id do objecto caso exista

    public int sqlExisteFxCaminhoSite(Ficheiro dados) {
        int existencia = -1;
        try {
            Connection ligacao = connection();
            Statement select = ligacao.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
            ResultSet result = select.executeQuery("SELECT ID, CAMINHOSITE FROM \"FICHEIROS\" WHERE CAMINHOSITE = '"
                    + dados.getCaminhosite() + "'");

            System.err.println("TESTE PARA LISTAR TUDO E VER SE EXISTE CAMINHOSITE");
            int conta = 0;

            if (result.last()) {
              conta = result.getRow();
              result.beforeFirst(); // not rs.first() because the rs.next() below will move on, missing the first element
            }
            
            while (result.next()) {
                if (conta > 0) {
                    System.err.println("Encontrado registo existente com ID: " + result.getString("ID")
                            + " e CaminhoSite: " + result.getString("CAMINHOSITE"));
                    existencia = result.getInt("ID");

                } else {
                    System.err.println("NAO encontrado registo existente com ID: " + result.getString("ID")
                            + " e CaminhoSite: " + result.getString("CAMINHOSITE"));
                }
            }
            select.close();
            ligacao.close();
        } catch (SQLException se) {
            if ((se.getErrorCode() == 30000) && ("42X05".equals(se.getSQLState()))) {
                System.out.println("Erro ao fazer SELECT: Tabela nao existente. public boolean sqlExisteFxCaminhoSite(Ficheiro dados)");
            } else {
                System.err.println("Erro inesperado ao fazer SELECT. public boolean sqlExisteFxCaminhoSite(Ficheiro dados)");
                printSQLException(se);
            }
        }
        return existencia;
    }

// Para saber se já existe o ficheiro passando o ID
    public boolean sqlExisteId(int idFicheiro) {
        boolean existencia = false;
        System.out.println("Vou testar se existe por ID: " + idFicheiro);

        try {
            Connection ligacao = connection();
            Statement select = ligacao.createStatement();
            ResultSet result = select.executeQuery("SELECT ID FROM \"FICHEIROS\" WHERE \"ID\"="
                    + idFicheiro);

            while (result.next()) { // processa resultados, um a um
                if (result.getInt(1) > 0) {
                    existencia = true;
                }
            }
            select.close();
            ligacao.close();
        } catch (SQLException se) {
            if ((se.getErrorCode() == 30000) && ("42X05".equals(se.getSQLState()))) {
                System.err.println("Erro ao fazer SELECT: Tabela nao existente. public boolean sqlExisteId(int idFicheiro)");
            } else {
                System.err.println("Erro inesperado ao fazer SELECT. public boolean sqlExisteId(int idFicheiro)");
                printSQLException(se);
            }
        }
        return existencia;
    }

// Para devolver Array com lista de todos os FX do dominio
    public ArrayList<Ficheiro> getByDomain(String dominio) {
        ArrayList<Ficheiro> lista = new ArrayList<Ficheiro>();

        try {
            Connection ligacao = connection();
            Statement select = ligacao.createStatement();
            ResultSet result = select.executeQuery("SELECT * from \"FICHEIROS\""
                    + "where \"DOMINIO\" = '" + dominio + "'");


            System.out.println("Get tudo do dominio :" + dominio);
            while (result.next()) { // process results one row at a time
                Ficheiro fx = new Ficheiro(
                        result.getInt("ID"),
                        result.getString("DOMINIO"),
                        result.getString("FICHEIRO"),
                        result.getString("ESTADO"),
                        result.getLong("TAMANHOSITE"),
                        result.getString("CAMINHOSITE"),
                        result.getString("CAMINHOLOCAL"),
                        result.getString("TIPO"),
                        result.getInt("NIVEIS"),
                        result.getDate("ACTUALIZADO"));
                lista.add(fx);
            }
            select.close();
            ligacao.close();
        } catch (SQLException se) {
            if ((se.getErrorCode() == 30000) && ("42X05".equals(se.getSQLState()))) {
                System.out.println("Erro ao fazer SELECT: Tabela nao existente. public ArrayList<Ficheiro> getByDomain(String dominio)");
            } else {
                System.err.println("Erro inesperado ao fazer SELECT. public ArrayList<Ficheiro> getByDomain(String dominio)");
                printSQLException(se);
            }
        }

        return lista;
    }

// Para devolver Array com lista de todos os fx INCOMPLETE do dominio
    public ArrayList<Ficheiro> getIncompleteByDomain(String dominio) {
        ArrayList<Ficheiro> lista = new ArrayList<Ficheiro>();
        Ficheiro fxEstado = new Ficheiro();

        String estado = fxEstado.DB_STATE_INCOMPLETE;

        try {
            Connection ligacao = connection();
            Statement select = ligacao.createStatement();
            ResultSet result = select.executeQuery("SELECT * from \"FICHEIROS\""
                    + "where \"DOMINIO\" = '" + dominio + "' and ESTADO = '"
                    + estado.toUpperCase() + "'");


            System.out.println("Get " + estado + " do dominio :" + dominio);
            while (result.next()) { // process results one row at a time
                Ficheiro fx = new Ficheiro(
                        result.getInt("ID"),
                        result.getString("DOMINIO"),
                        result.getString("FICHEIRO"),
                        result.getString("ESTADO"),
                        result.getLong("TAMANHOSITE"),
                        result.getString("CAMINHOSITE"),
                        result.getString("CAMINHOLOCAL"),
                        result.getString("TIPO"),
                        result.getInt("NIVEIS"),
                        result.getDate("ACTUALIZADO"));
                lista.add(fx);
            }
            select.close();
            ligacao.close();
        } catch (SQLException se) {
            if ((se.getErrorCode() == 30000) && ("42X05".equals(se.getSQLState()))) {
                System.out.println("Erro ao fazer SELECT: Tabela nao existente. public ArrayList<Ficheiro> getIncompleteByDomain(String dominio)");
            } else {
                System.err.println("Erro inesperado ao fazer SELECT. public ArrayList<Ficheiro> getIncompleteByDomain(String dominio)");
                printSQLException(se);
            }
        }

        return lista;
    }

// Para devolver Array com lista de todos os fx DOWNLOAD do dominio
    public ArrayList<Ficheiro> getDownloadByDomain(String dominio) {
        ArrayList<Ficheiro> lista = new ArrayList<>();
        Ficheiro fxEstado = new Ficheiro();

        String estado = fxEstado.DB_STATE_DOWNLOAD;

        try {
            Connection ligacao = connection();
            Statement select = ligacao.createStatement();
            ResultSet result = select.executeQuery("SELECT * from \"FICHEIROS\""
                    + "where DOMINIO = '" + dominio + "' and ESTADO = '"
                    + estado.toUpperCase() + "'");


            System.out.println("Get " + estado + " do dominio :" + dominio);
            while (result.next()) { // process results one row at a time
                Ficheiro fx = new Ficheiro(
                        result.getInt("ID"),
                        result.getString("DOMINIO"),
                        result.getString("FICHEIRO"),
                        result.getString("ESTADO"),
                        result.getLong("TAMANHOSITE"),
                        result.getString("CAMINHOSITE"),
                        result.getString("CAMINHOLOCAL"),
                        result.getString("TIPO"),
                        result.getInt("NIVEIS"),
                        result.getDate("ACTUALIZADO"));
                lista.add(fx);
            }
            select.close();
            ligacao.close();
        } catch (SQLException se) {
            if ((se.getErrorCode() == 30000) && ("42X05".equals(se.getSQLState()))) {
                System.out.println("Erro ao fazer SELECT: Tabela nao existente. public ArrayList<Ficheiro> getDownloadByDomain(String dominio)");
            } else {
                System.err.println("Erro inesperado ao fazer SELECT. public ArrayList<Ficheiro> getDownloadByDomain(String dominio)");
                printSQLException(se);
            }
        }

        return lista;
    }

// Para devolver Array com lista de todos os fx PARSE do dominio
    public ArrayList<Ficheiro> getParseByDomain(String dominio) {
        ArrayList<Ficheiro> lista = new ArrayList<>();
        Ficheiro fxEstado = new Ficheiro();

        String estado = fxEstado.DB_STATE_PARSE;

        try {
            Connection ligacao = connection();
            Statement select = ligacao.createStatement();
            ResultSet result = select.executeQuery("SELECT * from \"FICHEIROS\""
                    + " where DOMINIO = '" + dominio + "' and ESTADO = '" + fxEstado.DB_STATE_PARSE + "'");

            System.err.println("Get " + estado + " do dominio :" + dominio);
            while (result.next()) { // process results one row at a time
                Ficheiro fx = new Ficheiro(
                        result.getInt("ID"),
                        result.getString("DOMINIO"),
                        result.getString("FICHEIRO"),
                        result.getString("ESTADO"),
                        result.getLong("TAMANHOSITE"),
                        result.getString("CAMINHOSITE"),
                        result.getString("CAMINHOLOCAL"),
                        result.getString("TIPO"),
                        result.getInt("NIVEIS"),
                        result.getDate("ACTUALIZADO"));
                lista.add(fx);
            }
            select.close();
            ligacao.close();
        } catch (SQLException se) {
            if ((se.getErrorCode() == 30000) && ("42X05".equals(se.getSQLState()))) {
                System.out.println("Erro ao fazer SELECT: Tabela nao existente.  public ArrayList<Ficheiro> getParseByDomain(String dominio)");
            } else {
                System.err.println("Erro inesperado ao fazer SELECT.  public ArrayList<Ficheiro> getParseByDomain(String dominio)");
                printSQLException(se);
            }
        }

        return lista;
    }

// Para devolver Array com lista de todos os fx PENDING do dominio
    public ArrayList<Ficheiro> getPendingByDomain(String dominio) {
        ArrayList<Ficheiro> lista = new ArrayList<Ficheiro>();
        Ficheiro fxEstado = new Ficheiro();

        String estado = fxEstado.DB_STATE_PENDING;

        try {
            Connection ligacao = connection();
            Statement select = ligacao.createStatement();
            ResultSet result = select.executeQuery("SELECT * from \"FICHEIROS\""
                    + "where \"DOMINIO\" = '" + dominio + "' and ESTADO = '"
                    + estado.toUpperCase() + "'");


            System.out.println("Get " + estado + " do dominio :" + dominio);
            while (result.next()) { // process results one row at a time
                Ficheiro fx = new Ficheiro(
                        result.getInt("ID"),
                        result.getString("DOMINIO"),
                        result.getString("FICHEIRO"),
                        result.getString("ESTADO"),
                        result.getLong("TAMANHOSITE"),
                        result.getString("CAMINHOSITE"),
                        result.getString("CAMINHOLOCAL"),
                        result.getString("TIPO"),
                        result.getInt("NIVEIS"),
                        result.getDate("ACTUALIZADO"));
                lista.add(fx);
            }
            select.close();
            ligacao.close();
        } catch (SQLException se) {
            if ((se.getErrorCode() == 30000) && ("42X05".equals(se.getSQLState()))) {
                System.out.println("Erro ao fazer SELECT: Tabela nao existente. public ArrayList<Ficheiro> getPendingByDomain(String dominio)");
            } else {
                System.err.println("Erro inesperado ao fazer SELECT. public ArrayList<Ficheiro> getPendingByDomain(String dominio)");
                printSQLException(se);
            }
        }

        return lista;
    }

// Para devolver Array com lista de todos os fx DOWNLOADING do dominio
    public ArrayList<Ficheiro> getDownloadingByDomain(String dominio) {
        ArrayList<Ficheiro> lista = new ArrayList<Ficheiro>();
        Ficheiro fxEstado = new Ficheiro();

        String estado = fxEstado.DB_STATE_DOWNLOADING;


        try {
            Connection ligacao = connection();
            Statement select = ligacao.createStatement();
            ResultSet result = select.executeQuery("SELECT * from \"FICHEIROS\""
                    + "where \"DOMINIO\" = '" + dominio + "' and ESTADO = '"
                    + estado.toUpperCase() + "'");


            System.out.println("Get " + estado + " do dominio :" + dominio);
            while (result.next()) { // process results one row at a time
                Ficheiro fx = new Ficheiro(
                        result.getInt("ID"),
                        result.getString("DOMINIO"),
                        result.getString("FICHEIRO"),
                        result.getString("ESTADO"),
                        result.getLong("TAMANHOSITE"),
                        result.getString("CAMINHOSITE"),
                        result.getString("CAMINHOLOCAL"),
                        result.getString("TIPO"),
                        result.getInt("NIVEIS"),
                        result.getDate("ACTUALIZADO"));
                lista.add(fx);
            }
            select.close();
            ligacao.close();
        } catch (SQLException se) {
            if ((se.getErrorCode() == 30000) && ("42X05".equals(se.getSQLState()))) {
                System.out.println("Erro ao fazer SELECT: Tabela nao existente. public ArrayList<Ficheiro> getDownloadingByDomain(String dominio)");
            } else {
                System.err.println("Erro inesperado ao fazer SELECT. public ArrayList<Ficheiro> getDownloadingByDomain(String dominio)");
                printSQLException(se);
            }
        }

        return lista;
    }

// Para devolver Array com lista de todos os fx PARSING do dominio
    public ArrayList<Ficheiro> getParsingByDomain(String dominio) {
        ArrayList<Ficheiro> lista = new ArrayList<Ficheiro>();
        Ficheiro fxEstado = new Ficheiro();

        String estado = fxEstado.DB_STATE_PARSING;

        try {
            Connection ligacao = connection();
            Statement select = ligacao.createStatement();
            ResultSet result = select.executeQuery("SELECT * from \"FICHEIROS\""
                    + "where \"DOMINIO\" = '" + dominio + "' and ESTADO = '"
                    + estado.toUpperCase() + "'");


            System.out.println("Get " + estado + " do dominio :" + dominio);
            while (result.next()) { // process results one row at a time
                Ficheiro fx = new Ficheiro(
                        result.getInt("ID"),
                        result.getString("DOMINIO"),
                        result.getString("FICHEIRO"),
                        result.getString("ESTADO"),
                        result.getLong("TAMANHOSITE"),
                        result.getString("CAMINHOSITE"),
                        result.getString("CAMINHOLOCAL"),
                        result.getString("TIPO"),
                        result.getInt("NIVEIS"),
                        result.getDate("ACTUALIZADO"));
                lista.add(fx);
            }
            select.close();
            ligacao.close();
        } catch (SQLException se) {
            if ((se.getErrorCode() == 30000) && ("42X05".equals(se.getSQLState()))) {
                System.out.println("Erro ao fazer SELECT: Tabela nao existente. public ArrayList<Ficheiro> getParsingByDomain(String dominio)");
            } else {
                System.err.println("Erro inesperado ao fazer SELECT. public ArrayList<Ficheiro> getParsingByDomain(String dominio)");
                printSQLException(se);
            }
        }

        return lista;
    }

// Para devolver Array com lista de todos os fx COMPLETE do dominio
    public ArrayList<Ficheiro> getCompleteByDomain(String dominio) {
        ArrayList<Ficheiro> lista = new ArrayList<Ficheiro>();
        Ficheiro fxEstado = new Ficheiro();

        String estado = fxEstado.DB_STATE_COMPLETE;

        try {
            Connection ligacao = connection();
            Statement select = ligacao.createStatement();
            ResultSet result = select.executeQuery("SELECT * from \"FICHEIROS\""
                    + "where \"DOMINIO\" = '" + dominio + "' and ESTADO = '"
                    + estado.toUpperCase() + "'");


            System.out.println("Get " + estado + " do dominio :" + dominio);
            while (result.next()) { // process results one row at a time
                Ficheiro fx = new Ficheiro(
                        result.getInt("ID"),
                        result.getString("DOMINIO"),
                        result.getString("FICHEIRO"),
                        result.getString("ESTADO"),
                        result.getLong("TAMANHOSITE"),
                        result.getString("CAMINHOSITE"),
                        result.getString("CAMINHOLOCAL"),
                        result.getString("TIPO"),
                        result.getInt("NIVEIS"),
                        result.getDate("ACTUALIZADO"));
                lista.add(fx);
            }
            select.close();
            ligacao.close();
        } catch (SQLException se) {
            if ((se.getErrorCode() == 30000) && ("42X05".equals(se.getSQLState()))) {
                System.out.println("Erro ao fazer SELECT: Tabela nao existente. public ArrayList<Ficheiro> getCompleteByDomain(String dominio)");
            } else {
                System.err.println("Erro inesperado ao fazer SELECT. public ArrayList<Ficheiro> getCompleteByDomain(String dominio)");
                printSQLException(se);
            }
        }

        return lista;
    }

// Para devolver Array com lista de todos os fx do dominio conforme ESTADO passado
    public ArrayList<Ficheiro> getByDomainStatus(String dominio, String status) {
        ArrayList<Ficheiro> lista = new ArrayList<Ficheiro>();
        String estado = status.toUpperCase();

        try {
            Connection ligacao = connection();
            Statement select = ligacao.createStatement();
            ResultSet result = select.executeQuery("SELECT * from \"FICHEIROS\""
                    + "where \"DOMINIO\" = '" + dominio + "' and ESTADO = '"
                    + estado + "'");


            System.out.println("Get " + estado + " do dominio :" + dominio);
            while (result.next()) { // process results one row at a time
                Ficheiro fx = new Ficheiro(
                        result.getInt("ID"),
                        result.getString("DOMINIO"),
                        result.getString("FICHEIRO"),
                        result.getString("ESTADO"),
                        result.getLong("TAMANHOSITE"),
                        result.getString("CAMINHOSITE"),
                        result.getString("CAMINHOLOCAL"),
                        result.getString("TIPO"),
                        result.getInt("NIVEIS"),
                        result.getDate("ACTUALIZADO"));
                lista.add(fx);
            }
            select.close();
            ligacao.close();
        } catch (SQLException se) {
            if ((se.getErrorCode() == 30000) && ("42X05".equals(se.getSQLState()))) {
                System.out.println("Erro ao fazer SELECT: Tabela nao existente. public ArrayList<Ficheiro> getByDomainStatus(String dominio, String status)");
            } else {
                System.err.println("Erro inesperado ao fazer SELECT. public ArrayList<Ficheiro> getByDomainStatus(String dominio, String status)");
                printSQLException(se);
            }
        }

        return lista;
    }

// Devolve um unico ficheiro conforme o id
    public Ficheiro getFicheiro(int id) {
        Ficheiro fx = null;

        try {
            Connection ligacao = connection();
            Statement select = ligacao.createStatement();
            ResultSet result = select.executeQuery("SELECT * from \"FICHEIROS\""
                    + "where \"ID\" = " + id + "");


            System.out.println("Get tudo do Ficheiro com id :" + id);
            while (result.next()) { // process results one row at a time
                fx = new Ficheiro(
                        result.getInt("ID"),
                        result.getString("DOMINIO"),
                        result.getString("FICHEIRO"),
                        result.getString("ESTADO"),
                        result.getLong("TAMANHOSITE"),
                        result.getString("CAMINHOSITE"),
                        result.getString("CAMINHOLOCAL"),
                        result.getString("TIPO"),
                        result.getInt("NIVEIS"),
                        result.getDate("ACTUALIZADO"));
            }
            select.close();
            ligacao.close();
        } catch (SQLException se) {
            if ((se.getErrorCode() == 30000) && ("42X05".equals(se.getSQLState()))) {
                System.out.println("Erro ao fazer SELECT: Tabela nao existente. public Ficheiro getFicheiro(int id)");
            } else {
                System.err.println("Erro inesperado ao fazer SELECT. public Ficheiro getFicheiro(int id)");
                printSQLException(se);
            }
        }

        return fx;
    }

// Para devolver Array com lista de todos os fx BINARY do dominio
    public ArrayList<Ficheiro> getByTypeBinary(String dominio) {
        ArrayList<Ficheiro> lista = new ArrayList<Ficheiro>();
        Ficheiro fxEstado = new Ficheiro();

        String tipo = fxEstado.DB_TYPE_BINARY;

        try {
            Connection ligacao = connection();
            Statement select = ligacao.createStatement();
            ResultSet result = select.executeQuery("SELECT * from \"FICHEIROS\""
                    + "where \"DOMINIO\" = '" + dominio + "' and TIPO = '"
                    + tipo + "'");


            System.out.println("Get " + tipo + " do dominio :" + dominio);
            while (result.next()) { // process results one row at a time
                Ficheiro fx = new Ficheiro(
                        result.getInt("ID"),
                        result.getString("DOMINIO"),
                        result.getString("FICHEIRO"),
                        result.getString("ESTADO"),
                        result.getLong("TAMANHOSITE"),
                        result.getString("CAMINHOSITE"),
                        result.getString("CAMINHOLOCAL"),
                        result.getString("TIPO"),
                        result.getInt("NIVEIS"),
                        result.getDate("ACTUALIZADO"));
                lista.add(fx);
            }
            select.close();
            ligacao.close();
        } catch (SQLException se) {
            if ((se.getErrorCode() == 30000) && ("42X05".equals(se.getSQLState()))) {
                System.out.println("Erro ao fazer SELECT: Tabela nao existente. public ArrayList<Ficheiro> getByTypeBinary(String dominio)");
            } else {
                System.err.println("Erro inesperado ao fazer SELECT. public ArrayList<Ficheiro> getByTypeBinary(String dominio)");
                printSQLException(se);
            }
        }

        return lista;
    }

// Para devolver Array com lista de todos os fx HYPERTEXT do dominio
    public ArrayList<Ficheiro> getByTypeHypertext(String dominio) {
        ArrayList<Ficheiro> lista = new ArrayList<Ficheiro>();
        Ficheiro fxEstado = new Ficheiro();

        String tipo = fxEstado.DB_TYPE_HYPERTEXT;

        try {
            Connection ligacao = connection();
            Statement select = ligacao.createStatement();
            ResultSet result = select.executeQuery("SELECT * from \"FICHEIROS\""
                    + "where \"DOMINIO\" = '" + dominio + "' and TIPO = '"
                    + tipo + "'");


            System.out.println("Get " + tipo + " do dominio :" + dominio);
            while (result.next()) { // process results one row at a time
                Ficheiro fx = new Ficheiro(
                        result.getInt("ID"),
                        result.getString("DOMINIO"),
                        result.getString("FICHEIRO"),
                        result.getString("ESTADO"),
                        result.getLong("TAMANHOSITE"),
                        result.getString("CAMINHOSITE"),
                        result.getString("CAMINHOLOCAL"),
                        result.getString("TIPO"),
                        result.getInt("NIVEIS"),
                        result.getDate("ACTUALIZADO"));
                lista.add(fx);
            }
            select.close();
            ligacao.close();
        } catch (SQLException se) {
            if ((se.getErrorCode() == 30000) && ("42X05".equals(se.getSQLState()))) {
                System.out.println("Erro ao fazer SELECT: Tabela nao existente. public ArrayList<Ficheiro> getByTypeHypertext(String dominio)");
            } else {
                System.err.println("Erro inesperado ao fazer SELECT. public ArrayList<Ficheiro> getByTypeHypertext(String dominio)");
                printSQLException(se);
            }
        }

        return lista;
    }

////////////////////////////////////
//  EM TESTES E INVESTIGACAO A PARTIR DAQUI
////////////////////////////////////

    // Para tratamento de Excepcoes SQL
    public void printSQLException(SQLException e) {
        // Abre a SQLException e mostra o que se passou
        while (e != null) {
            System.err.println("\n----- SQLException -----");
            System.err.println("  SQL State:  " + e.getSQLState());
            System.err.println("  Error Code: " + e.getErrorCode());
            System.err.println("  Message:    " + e.getMessage());
            e = e.getNextException();
        }
    }
}
